﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.LIB.YJKControls;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public partial class FrmDuct : System.Windows.Forms.Form
	{
		public FrmDuct()
		{
			this.InitializeComponent();
			new YJKProcessTools().ShowInTaskbarChange(this);
		}

		public FrmDuct(ExternalCommandData commandData, List<Duct> iDuctList)
		{
			this.InitializeComponent();
			new YJKProcessTools().ShowInTaskbarChange(this);
			this.cmmData = commandData;
			this.listDuct = iDuctList;
		}

		private void FrmDuct_Load(object sender, EventArgs e)
		{
			try
			{
				this.uiDoc = this.cmmData.Application.ActiveUIDocument;
				this.Text = "风管编辑-共选择" + this.listDuct.Count + "条风管";
				this.ReadDuctParaInfo();
				this.InitialParamInfo(this.startParam);
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private void InitialParamInfo(JudgeDuctParam judgeDParam)
		{
			judgeDParam.DuctSysType = (ElementId)this.cmbDuctSysType.SelectedValue;
			judgeDParam.WidthorDiam = Convert.ToDouble(this.cmbWidthorDiameter.Text.Trim());
			judgeDParam.Height = Convert.ToDouble(this.cmbHeight.Text.Trim());
			judgeDParam.StartLevel = (ElementId)this.cmbLevel.SelectedValue;
			judgeDParam.Offset = Convert.ToDouble(this.txtOffsetLevel.Text);
			judgeDParam.FluxAdditional = Convert.ToDouble(this.txtFluxAdditional.Text);
		}

		private void ReadDuctParaInfo()
		{
			try
			{
				this.BindDSysType(this.uiDoc.Document, this.listDuct[0]);
				this.BindLevel(this.uiDoc.Document, this.listDuct[0]);
				this.ReadSectionType(this.listDuct[0]);
				this.ReadParaInfo(this.listDuct[0]);
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private void BindDSysType(Document doc, Duct duct)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc);
			new List<Element>();
			List<Element> list = filteredElementCollector.OfClass(typeof(MechanicalSystemType)).ToList<Element>();
			Parameter parameter = duct.GetParameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM);
			List<DuctSysType> list2 = new List<DuctSysType>();
			int num = 0;
			int selectedIndex = 0;
			foreach (Element element in list)
			{
				list2.Add(new DuctSysType
				{
					SysTypeId = element.Id,
					SysTypeName = element.Name
				});
				if (element.Name == doc.GetElementById(parameter.AsElementId()).Name)
				{
					selectedIndex = num;
				}
				num++;
			}
			this.cmbDuctSysType.DataSource = list2;
			this.cmbDuctSysType.ValueMember = "SysTypeId";
			this.cmbDuctSysType.DisplayMember = "SysTypeName";
			this.cmbDuctSysType.SelectedIndex = selectedIndex;
		}

		private void BindLevel(Document doc, Duct duct)
		{
			IEnumerable<Element> enumerable = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements();
			int num = 0;
			int selectedIndex = 0;
			List<DuctLevel> list = new List<DuctLevel>();
			foreach (Element element in enumerable)
			{
				Level level = element as Level;
				list.Add(new DuctLevel
				{
					LevelId = level.Id,
					LevelName = level.Name
				});
				if (level != null)
				{
					if (level.Name == duct.ReferenceLevel.Name)
					{
						selectedIndex = num;
					}
					num++;
				}
			}
			this.cmbLevel.DataSource = list;
			this.cmbLevel.DisplayMember = "LevelName";
			this.cmbLevel.ValueMember = "LevelId";
			this.cmbLevel.SelectedIndex = selectedIndex;
		}

		private void ReadParaInfo(Duct duct)
		{
			Parameter parameter = duct.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM);
            string str = Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, parameter.AsDouble()) / 1000.0);
			this.txtOffsetLevel.Text = Convert.ToDouble(StringTools.CutOffEfficacious(str, 2)).ToString();
			parameter = duct.GetParameter(BuiltInParameter.RBS_DUCT_FLOW_PARAM);
            this.txtFlux.Text = Convert.ToDouble(StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)66, parameter.AsDouble())), 2)).ToString();
			parameter = duct.GetParameter(BuiltInParameter.RBS_ADDITIONAL_FLOW);
            this.txtFluxAdditional.Text = Convert.ToDouble(StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)66, parameter.AsDouble())), 2)).ToString();
			parameter = duct.GetParameter(BuiltInParameter.RBS_VELOCITY);
            this.txtSpeed.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)61, parameter.AsDouble())), 2);
			parameter = duct.GetParameter(BuiltInParameter.RBS_FRICTION);
            this.txtAttrition.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)38, parameter.AsDouble())), 2);
			parameter = duct.GetParameter(BuiltInParameter.RBS_PRESSURE_DROP);
            this.txtResistance.Text = StringTools.CutOffEfficacious(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)48, parameter.AsDouble())), 2);
		}

		private void ReadSectionType(Duct duct)
		{
			DuctShape ductShape = 0;
			Parameter parameter = null;
			foreach (object obj in duct.ConnectorManager.Connectors)
			{
				Connector connector = (Connector)obj;
				if (connector.Shape == ConnectorSharp.Oval)
				{
					this.txtSectionType.Text = "椭圆形风管";
                    this.BindWidthandHeight(duct, parameter, (DuctShape)2);
                    ductShape = (DuctShape)2;
				}
				else if (connector.Shape == ConnectorSharp.Rect)
				{
					this.txtSectionType.Text = "矩形风管";
                    this.BindWidthandHeight(duct, parameter, (DuctShape)1);
                    ductShape = (DuctShape)1;
				}
				else if (connector.Shape == ConnectorSharp.Round)
				{
					this.txtSectionType.Text = "圆形风管";
					parameter = duct.GetParameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);
                    this.cmbWidthorDiameter.Text = Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, parameter.AsDouble()));
					this.cmbHeight.Text = this.cmbWidthorDiameter.Text;
					this.cmbHeight.Enabled = false;
					this.ckbHeight.Enabled = false;
					ductShape = 0;
				}
			}
			DuctSizeSettingIterator ductSizeSettingIterator = DuctSizeSettings.GetDuctSizeSettings(this.uiDoc.Document).GetDuctSizeSettingIterator();
			this.cmbWidthorDiameter.Items.Clear();
			this.cmbHeight.Items.Clear();
			while (ductSizeSettingIterator.MoveNext())
			{
				KeyValuePair<DuctShape, DuctSizes> keyValuePair = ductSizeSettingIterator.Current;
				if (keyValuePair.Key == ductShape)
				{
					keyValuePair = ductSizeSettingIterator.Current;
					DuctSizeIterator ductSizeIterator = keyValuePair.Value.GetDuctSizeIterator();
					while (ductSizeIterator.MoveNext())
					{
						MEPSize mepsize = ductSizeIterator.Current;
                        this.cmbWidthorDiameter.Items.Add(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, mepsize.NominalDiameter)));
                        this.cmbHeight.Items.Add(Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, ductSizeIterator.Current.NominalDiameter)));
					}
				}
			}
		}

		private void BindWidthandHeight(Duct duct, Parameter para, DuctShape dShape)
		{
			if (!this.ckbHeight.Enabled)
			{
				this.ckbHeight.Enabled = true;
			}
			if (!this.cmbHeight.Enabled)
			{
				this.cmbHeight.Enabled = true;
			}
			para = duct.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
            this.cmbWidthorDiameter.Text = Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, para.AsDouble()));
			para = duct.GetParameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
            this.cmbHeight.Text = Convert.ToString(UnitConvert.CovertFromAPI((DisplayUnitType)2, para.AsDouble()));
		}

		private void btnExit_Click(object sender, EventArgs e)
		{
			RevitVersionFuncs.ClearSelection(this.uiDoc.Selection);
			base.Dispose();
		}

		private void btnReSelect_Click(object sender, EventArgs e)
		{
			try
			{
				base.DialogResult = DialogResult.Retry;
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
		}

		private void btnModify_Click(object sender, EventArgs e)
		{
			Transaction transaction = null;
			try
			{
				if (!this.JudgeCheckInfo())
				{
					MessageBox.Show("请勾选需修改的参数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				string text = this.cmbWidthorDiameter.Text;
				if (!Regex.IsMatch(text, "^[1-9]+\\d*$"))
				{
					MessageBox.Show("宽度或直径必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				if (Convert.ToInt32(text) > 100000)
				{
					MessageBox.Show("请确认输入正确的风管宽度！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return;
				}
				string text2 = this.cmbHeight.Text;
				if (!Regex.IsMatch(text2, "^[1-9]+\\d*$"))
				{
					MessageBox.Show("高度必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				if (Convert.ToInt32(text2) > 100000)
				{
					MessageBox.Show("请确认输入正确的风管高度！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return;
				}
				string text3 = this.txtOffsetLevel.Text;
				if (!Regex.IsMatch(text3, "^[+-]?\\d*[.]?\\d*"))
				{
					MessageBox.Show("偏移量必须是数字！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					return;
				}
				string text4 = this.txtFluxAdditional.Text;
				transaction = new Transaction(this.uiDoc.Document, "修改风管");
				transaction.Start();
				if (this.JudgeModifyParaInfo(this.listDuct, text, text2, text3, text4))
				{
					MessageBox.Show("修改成功！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					this.uiDoc.Document.Regenerate();
					transaction.Commit();
				}
				else
				{
					MessageBox.Show("修改失败！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
					transaction.RollBack();
				}
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
					if ((int)status == 1)
					{
						transaction.Commit();
					}
					else if ((int)status == 5)
					{
						transaction.RollBack();
					}
				}
			}
			base.DialogResult = DialogResult.OK;
		}

		private bool JudgeCheckInfo()
		{
			return this.ckbDuctSysType.Checked || this.ckbHeight.Checked || this.ckbLevel.Checked || this.ckbOffsetLevel.Checked || this.ckbWidthorDiameter.Checked || this.ckbFluxAdditional.Checked;
		}

		private bool JudgeModifyParaInfo(List<Duct> listDuct, string width, string height, string offset, string szFluxAdditional)
		{
			Parameter parameter = null;
			List<bool> list = new List<bool>();
			foreach (Duct duct in listDuct)
			{
				if (this.ckbDuctSysType.Checked)
				{
					parameter = duct.GetParameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM);
					list.Add(parameter.Set((ElementId)this.cmbDuctSysType.SelectedValue));
				}
				YJKRevitTools.SetSystemSimple(this.uiDoc.Document, duct);
				foreach (object obj in duct.ConnectorManager.Connectors)
				{
					Connector connector = (Connector)obj;
					if (connector.Shape == ConnectorSharp.Oval)
					{
						this.ModifyWidthHeightInfo(ref parameter, list, duct, width, height);
					}
					else if (connector.Shape == ConnectorSharp.Rect)
					{
						this.ModifyWidthHeightInfo(ref parameter, list, duct, width, height);
					}
					else if (connector.Shape == ConnectorSharp.Round && this.ckbWidthorDiameter.Checked)
					{
						parameter = duct.GetParameter(BuiltInParameter.RBS_CURVE_DIAMETER_PARAM);
						list.Add(parameter.Set(UnitConvert.CovertToAPI(Convert.ToDouble(this.cmbWidthorDiameter.Text), (Autodesk.Revit.DB.DisplayUnitType)2)));
					}
				}
				if (this.ckbLevel.Checked)
				{
					parameter = duct.GetParameter(BuiltInParameter.RBS_START_LEVEL_PARAM);
					list.Add(parameter.Set((ElementId)this.cmbLevel.SelectedValue));
				}
				if (this.ckbOffsetLevel.Checked)
				{
					parameter = duct.GetParameter(BuiltInParameter.RBS_OFFSET_PARAM);
					list.Add(parameter.Set(UnitConvert.CovertToAPI(Convert.ToDouble(offset) * 1000.0, (Autodesk.Revit.DB.DisplayUnitType)2)));
				}
				if (this.ckbFluxAdditional.Checked)
				{
					parameter = duct.GetParameter(BuiltInParameter.RBS_ADDITIONAL_FLOW);
					list.Add(parameter.Set(UnitConvert.CovertToAPI(Convert.ToDouble(szFluxAdditional), (Autodesk.Revit.DB.DisplayUnitType)66)));
				}
			}
			if (list.Count == 0)
			{
				return false;
			}
			using (List<bool>.Enumerator enumerator3 = list.GetEnumerator())
			{
				while (enumerator3.MoveNext())
				{
					if (!enumerator3.Current)
					{
						return false;
					}
				}
			}
			return true;
		}

		private void ModifyWidthHeightInfo(ref Parameter para, IList<bool> listMsg, Duct item, string width, string height)
		{
			if (this.ckbWidthorDiameter.Checked)
			{
				para = item.GetParameter(BuiltInParameter.RBS_CURVE_WIDTH_PARAM);
				listMsg.Add(para.Set(UnitConvert.CovertToAPI(Convert.ToDouble(width), (Autodesk.Revit.DB.DisplayUnitType)2)));
			}
			if (this.ckbHeight.Checked)
			{
				para = item.GetParameter(BuiltInParameter.RBS_CURVE_HEIGHT_PARAM);
				listMsg.Add(para.Set(UnitConvert.CovertToAPI(Convert.ToDouble(height), (Autodesk.Revit.DB.DisplayUnitType)2)));
			}
		}

		private void txtWidthorDiameter_Leave(object sender, EventArgs e)
		{
			if (!Regex.IsMatch(this.cmbWidthorDiameter.Text, "^[1-9]+\\d*$"))
			{
				MessageBox.Show("宽度或直径必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}

		private void txtHeight_Leave(object sender, EventArgs e)
		{
			if (!Regex.IsMatch(this.cmbHeight.Text, "^[1-9]+\\d*$"))
			{
				MessageBox.Show("高度必须是正整数！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}

		private void txtOffsetLevel_Leave(object sender, EventArgs e)
		{
			if (!Regex.IsMatch(this.txtOffsetLevel.Text, "^[+-]?[0-9]+\\d*[.]?\\d*$"))
			{
				MessageBox.Show("偏移量必须是数字！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
				return;
			}
		}

		private List<Duct> listDuct = new List<Duct>();

		private ExternalCommandData cmmData;

		private UIDocument uiDoc;

		private JudgeDuctParam startParam = new JudgeDuctParam();

		private JudgeDuctParam judgeParam = new JudgeDuctParam();
	}
}
